#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "ohos_types.h"
#include "cmsis_os2.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include "iot_i2c.h"

#define IOT_I2C 1
#define OLED_ADDRESS (0x3c << 1)
#define OLED_REG_CMD 0x00
#define OLED_REG_DATA 0x40

uint32_t oled_write(uint8_t reg, uint8_t data)
{
    uint8_t buffer[] = {reg, data};
    return IoTI2cWrite(IOT_I2C, OLED_ADDRESS, buffer, 2);
}

uint32_t oled_init(void)
{
    uint8_t cmds[] = {0xAE, 0x00, 0x10, 0x40, 0xB0, 0x81, 0xFF, 0xA1, 0xA6, 0xA8, 0x3F, 0xC8, 0xD3, 0x00, 0xD5, 0x80, 0xD8, 0x05, 0xD9, 0xF1, 0xDA, 0x12, 0xDB, 0x30, 0x8D, 0x14, 0xAF};
    for (size_t i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++)
    {
        uint32_t status = oled_write(OLED_REG_CMD, cmds[i]);
        if (status != IOT_SUCCESS)
        {
            return status;
        }
    }
}

void oled_set_pos(uint8_t x, uint8_t y)
{
    oled_write(OLED_REG_CMD, 0xb0 + y);
    oled_write(OLED_REG_CMD, 0x10 | ((x & 0xf0) >> 4));
    oled_write(OLED_REG_CMD, x & 0x0f);
}

void oled_fill(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t data)
{
    for (uint8_t i = 0; i < height; i++)
    {
        oled_set_pos(x, y + i);
        for (uint8_t j = 0; j < width; j++)
        {
            oled_write(OLED_REG_DATA, data);
        }
    }
}

static void I2CTask(void)
{
    uint8_t ret;
    // GPIO0 复用为 I2C1 SDA
    IoTGpioInit(0);
    IoTGpioSetFunc(0, IOT_GPIO_FUNC_GPIO_0_I2C1_SDA);
    IoTGpioSetDir(0, IOT_GPIO_DIR_OUT);
    // GPIO1 复用为 I2C1 SCL
    IoTGpioInit(1);
    IoTGpioSetFunc(1, IOT_GPIO_FUNC_GPIO_1_I2C1_SCL);
    IoTGpioSetDir(1, IOT_GPIO_DIR_OUT);
    // 初始化 I2C1，速率 400kbps
    ret = IoTI2cInit(IOT_I2C, 400000);
    if (ret != IOT_SUCCESS)
    {
        printf("Failed to init I2C! Error: %d\n", ret);
        return;
    }
    // 初始化 OLED 屏幕
    ret = oled_init();
    if (ret != IOT_SUCCESS)
    {
        printf("Failed to init OLED! Error: %d\n", ret);
        return;
    }
    // 清屏并绘制矩形
    oled_fill(0, 0, 128, 8, 0x00);
    oled_fill(20, 2, 60, 3, 0xff);
    while (1)
    {
        sleep(1);
    }
}

void I2CExample(void)
{
    osThreadAttr_t attr;
    attr.name = "I2CTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 2048;
    attr.priority = osPriorityNormal;
    if (osThreadNew((osThreadFunc_t) I2CTask, NULL, &attr) == NULL)
    {
        printf("Failed to create I2CTask!\n");
    }
}

SYS_RUN(I2CExample);
